import { BLOCK_HEADER_HEIGHT, MODAL_FOOTER_HEIGHT, MODAL_HEADER_HEIGHT, MODAL_PADDING_HEIGHT } from '@/utils/utils';
import { Button, Col, Row, Tooltip } from 'antd';
import { Grid, Header } from 'gantd';
import React, { Dispatch, useCallback, useEffect, useMemo, useState } from 'react';
import { connect } from 'umi';
import { categoryColumns, groupColumns } from './static';

interface SelectorViewProps {
    multiple?: boolean,
    excludeId?: string,
    modalHei?: number | undefined,
    onChange?: (selectedRowKeys: string[], selectedRows: object[]) => void,
    [propName: string]: any
}

const SelectorView = React.forwardRef((props: SelectorViewProps, ref: any) => {
    const {
        multiple,
        modalHei,
        tableHei,
        visible,
        selectedRowKeys,
        selectedRows,
        setSelectedItem,
        onChange,
        onCategoryReload,
        currentUser,
        withAuth,
        listCategoryLoading,
        listUserGroupLoading,
        listUserGroupCategory,
        listUserGroupCategoryByAuth,
        listUserGroupTree,
        save,
        fetchListCategory,
        fetchListUserGroup,
    } = props;

    const [categoryRowsSelected, setCategoryRowsSelected] = useState<any[]>([]);

    useEffect(() => {
        if (categoryRowsSelected.length) setSelectedItem([], [])
    }, [categoryRowsSelected])

    useEffect(() => {
        return () => save({ listUserGroupTree: [] })
    }, [])

    useEffect(() => {
        if (typeof visible === 'boolean') {
            visible && initFetch()
        } else {
            initFetch()
        }
    }, [visible])

    const initFetch = useCallback(() => {
        if (withAuth && listUserGroupCategoryByAuth.length || !withAuth && listUserGroupCategory.length) return;
        loadCategory();
    }, [listUserGroupCategory, listUserGroupCategoryByAuth, withAuth])

    const loadCategory = useCallback(() => {
        fetchListCategory({ withAuth })
        onCategoryReload && onCategoryReload()
    }, [withAuth])

    const loadGroup = useCallback((item: any) => {
        if (!item) return
        fetchListUserGroup({ id: item.id, withAuth })
    }, [withAuth])

    const handlerSelectCategory = useCallback((_selectedRowKeys: any, _selectedRows: any[]) => {
        setCategoryRowsSelected(_selectedRows);
        loadGroup(_selectedRows[0]);
    }, [loadGroup])

    const handlerSelect = useCallback((_selectedRowKeys: string[], _selectedRows: object[]) => {
        setSelectedItem(_selectedRowKeys, _selectedRows)
        onChange && onChange(_selectedRowKeys, _selectedRows);
    }, [])

    const tableHeight = useMemo(() => {
        let diff = BLOCK_HEADER_HEIGHT + MODAL_HEADER_HEIGHT + MODAL_PADDING_HEIGHT * 2 + MODAL_FOOTER_HEIGHT
        if (!modalHei) return tableHei;
        let hei = modalHei - diff;
        return hei > 0 && hei || 'auto'
    }, [modalHei, tableHei])

    const categoryDataSource = useMemo(() => {
        return withAuth && listUserGroupCategoryByAuth || listUserGroupCategory;
    }, [withAuth, listUserGroupCategory, listUserGroupCategoryByAuth]);

    return (
        <Row>
            <Col span={8}>
                <Header
                    title={tr('类别列表')}
                    type="line"
                    extra={<Tooltip title={tr('刷新')}>
                        <Button size="small" icon='reload' onClick={loadCategory} />
                    </Tooltip>}
                />
                <Grid
                    hideMenuItemExport
                    rowkey="id"
                    columns={categoryColumns}
                    dataSource={categoryDataSource}
                    height={tableHeight}
                    loading={listCategoryLoading}
                    rowSelection={{
                        type: 'single',
                        selectedRows: categoryRowsSelected,
                        onSelect: handlerSelectCategory,
                    }}
                />
            </Col>
            <Col span={16}>
                <Header
                    title={tr('列表')}
                    type="line"
                    extra={<Tooltip title={tr('刷新')}>
                        <Button size="small" icon='reload' onClick={() => loadGroup(categoryRowsSelected[0])} />
                    </Tooltip>}
                />
                <Grid
                    hideMenuItemExport
                    rowkey="id"
                    columns={groupColumns}
                    dataSource={categoryRowsSelected.length ? listUserGroupTree : []}
                    treeData
                    groupSuppressAutoColumn
                    height={tableHeight}
                    loading={listUserGroupLoading}
                    boxColumnIndex={['groupCode', 'groupName']}
                    rowSelection={{
                        type: multiple ? 'multiple' : 'single',
                        selectedKeys: selectedRowKeys,
                        selectedRows,
                        onSelect: handlerSelect,
                    }}
                />
            </Col>
        </Row>)
})

SelectorView.defaultProps = {
    multiple: false,
    defaultSelectedKeys: [],
    tableHei: 'auto',
    withAuth: false
}

export interface ConnectProps extends SelectorViewProps {
    viewRef: any,
}

class ConnectComp extends React.Component<ConnectProps> {
    state = {
        selectedRowKeys: [],
        selectedRows: [],
    }
    static defaultProps = {
        viewRef: {}
    }
    componentDidMount() {
        this.props.viewRef.current = this;
    }
    setSelectedItem = (selectedRowKeys: [string], selectedRows: [any]) => {
        this.setState({ selectedRowKeys, selectedRows })
    }
    getValues = () => {
        const { selectedRowKeys, selectedRows } = this.state;
        return { selectedRowKeys, selectedRows }
    }
    render() {
        const { selectedRowKeys, selectedRows } = this.state;
        return <SelectorView
            {...this.props}
            selectedRowKeys={selectedRowKeys}
            selectedRows={selectedRows}
            setSelectedItem={this.setSelectedItem}
        />
    }
}

export default connect(({ selectors, user, loading }: any) => ({
    currentUser: user.currentUser,
    listCategoryLoading: loading.effects['selectors/fetchListCategory'],
    listUserGroupLoading: loading.effects['selectors/fetchListUserGroup'],
    listUserGroupCategory: selectors.listUserGroupCategory,
    listUserGroupCategoryByAuth: selectors.listUserGroupCategoryByAuth,
    listUserGroupTree: selectors.listUserGroupTree,
}), (dispatch: Dispatch<any>) => ({
    fetchListCategory: (payload: any) => dispatch({ type: 'selectors/fetchListCategory', payload }),
    fetchListUserGroup: (payload: any) => dispatch({ type: 'selectors/fetchListUserGroup', payload }),
    save: (payload: any) => dispatch({ type: 'selectors/save', payload })
}))(ConnectComp);